﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Lidgren.Network;
using EclipseLib.Shared;
using System.IO;
using EclipseLib.Shared.Scripting;
using Server.Management;

namespace Server
{
    public partial class FrmServer : Form
    {
        // Data Members
        Thread ServerThread;

        // Constructors
        public FrmServer()
        {
            InitializeComponent();
        }

        // Loading, Start Server
        protected override void OnLoad(EventArgs e)
        {
            Network.InitServer(LstLog);
            Network.Socket.OnReceiveData += new ServerSocket.ReceiveData(HandleData);
            ServerThread = new Thread(Network.Listen);
            ServerThread.Start();
        }

        // Form CLosing, Exit Server
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            Network.Running = false;

            while (ServerThread.IsAlive)
                Thread.Sleep(1);

            NetOutgoingMessage Packet = Network.CreateMessage();
            Packet.Write((Int32)ServerPackets.SendShutDown);
            Network.SendDataToAll(Packet);
        }

        // Handle Incoming Packets
        public void HandleData(int Index, NetIncomingMessage Msg)
        {
            switch (Msg.MessageType)
            {
                case NetIncomingMessageType.Data:
                    {
                        ClientPackets Packet = (ClientPackets)Msg.ReadInt32();

                        switch (Packet)
                        {
                            case ClientPackets.SendLogIn: HandleSendLogin(Index, Msg); break;
                            case ClientPackets.SendNewRegistration: HandleNewRegistration(Index, Msg); break;
                        }
                    }
                    break;
            }
        }

        // To Client Methods
        private void SendRegistrationResults(int Index, string Message)
        {
            NetOutgoingMessage Packet = Network.CreateMessage();
            Packet.Write((Int32)ServerPackets.SendRegistrationResults);
            Packet.Write(Message);
            Network.SendData(Index, Packet);
        }

        // Handle Data Functions
        private void HandleSendLogin(int Index, NetIncomingMessage Msg)
        {
            string UserName = Msg.ReadString();
            string Password = Msg.ReadString();

            // Does account exist?
            if (!File.Exists(@"Accounts\" + UserName + ".bin"))
            {
                Network.SendErrorMesage(Index, "Account: " + UserName + " does not exist!");
                return;
            }

            // Account Exists, is it being used?
            if (AccountManager.AccountBeingUsed(UserName))
            {
                Network.SendErrorMesage(Index, "Account: " + UserName + " is already logged in!");
                return;
            }

            // Safe to log in!
            if (!AccountManager.UseAccount(Index, UserName, Password))
            {
                Network.SendErrorMesage(Index, "Server Login Error!");
                return;
            }
            else
            {
                Account UserAccount = AccountManager.GetAccount(Index);

                NetOutgoingMessage Packet = Network.CreateMessage();
                Packet.Write((int)ServerPackets.SendLoginState);

                if (UserAccount.NewCharacter)
                    Packet.Write((int)LoginState.NewCharacter);
                else
                    Packet.Write((int)LoginState.PlayGame);

                Network.SendData(Index, Packet);
            }
        }
        private void HandleNewRegistration(int Index, NetIncomingMessage Msg)
        {
            string UserName = Msg.ReadString();
            string Password = Msg.ReadString();
            string Email = Msg.ReadString();

            if (!AccountManager.CreateNewAccount(UserName, Password, Email))
                SendRegistrationResults(Index, "Account already exists!");
            else
                SendRegistrationResults(Index, "Account created successfully!");
        }
    }
}
